package com.common.library.util;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.util.EntityUtils;
import org.json.JSONObject;
import org.xml.sax.InputSource;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.util.Xml.Encoding;

import com.zs4sdk.common.Extra;
import com.common.library.entity.JSONResultEntity;

public class NetworkHelper {
    private static final String TAG = NetworkHelper.class.getSimpleName();


    /**
     * 检查网络连接是否可用
     *
     * @param context 上下文
     * @return
     */
    public static boolean isNetworkAvailable(Context context) {
        ConnectivityManager cm = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        if (cm == null) {
            return false;
        }
        NetworkInfo[] netinfo = cm.getAllNetworkInfo();
        if (netinfo == null) {
            return false;
        }
        for (int i = 0; i < netinfo.length; i++) {
            if (netinfo[i].isConnected()) {
                return true;
            }
        }
        return false;
    }

    /**
     * 发送HttpPost消息
     *
     * @param url
     * @param postpair
     * @param useragent1
     * @return
     * @throws IOException
     * @throws ClientProtocolException
     */
    public static HttpResponse sendHttpPostString(String url,
                                                  List<NameValuePair> postpair, String useragent1) throws Exception {
//		LogUtil.i(TAG, "sendHttpPostString...url: " + url);
        if (Helper.isNotEmpty(url) && Helper.isNotEmpty(postpair)) {
//			try {
            HttpParams httpParameters = new BasicHttpParams();
            HttpConnectionParams.setConnectionTimeout(httpParameters, 10000);
            HttpConnectionParams.setSoTimeout(httpParameters, 45000);
            HttpClient httpClient = new DefaultHttpClient(httpParameters);
            HttpPost httpPost = new HttpPost(url);
            if (Helper.isNotEmpty(useragent1)) {
                httpPost.addHeader(Extra.NETWORK_KEY_USER_AGENT1, useragent1);
            }
            httpPost.setEntity(new UrlEncodedFormEntity(postpair));
            return httpClient.execute(httpPost);
//			} catch (Exception e) {
//				e.printStackTrace();
//			}
        }
        return null;
    }

    /**
     * 发送HttpGet消息
     *
     * @param url
     * @param useragent1
     * @return
     */
    public static HttpResponse sendHttpGetString(String url, String useragent1) throws Exception {
        if (Helper.isNotEmpty(url)) {
//			try {
//				LogUtil.i(TAG, "sendHttpPostString...url: " + url);
            HttpParams httpParameters = new BasicHttpParams();
            HttpConnectionParams.setConnectionTimeout(httpParameters, 10000);
            HttpConnectionParams.setSoTimeout(httpParameters, 45000);
            HttpClient httpclient = new DefaultHttpClient(httpParameters);
            HttpGet httpget = new HttpGet(url);
            if (Helper.isNotEmpty(useragent1)) {
                httpget.addHeader(Extra.NETWORK_KEY_USER_AGENT1, useragent1);
            }
            return httpclient.execute(httpget);
//			} catch (Exception e) {
//				e.printStackTrace();
//			}
        }
        return null;
    }

    /**
     * 网络请求是否成功
     *
     * @param response
     * @return 网络请求是否成功
     */
    public static boolean isHttpResponseSuccess(HttpResponse response) {
        boolean result = false;
        try {
            if (Helper.isNotNull(response)) {
                if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                    LogUtil.d(TAG, "发送成功！");
                    result = true;
                } else {
                    LogUtil.d(TAG, "发送失败:" + response.getStatusLine().toString());
                }
            } else {
                LogUtil.d(TAG, "服务器无响应！");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 取得网络请求返回的HttpEntity
     *
     * @param response
     * @return 返回的HttpEntity实例
     */
    public static HttpEntity getHttpResponseEntity(HttpResponse response) {
        HttpEntity result = null;
        if (isHttpResponseSuccess(response)) {
            result = response.getEntity();
        }
        return result;
    }

    /**
     * 取得网络请求返回的字符串内容
     *
     * @param response
     * @return
     */
    public static String getHttpResponseString(HttpResponse response) {
        return getHttpResponseString(response, Encoding.UTF_8.toString());
    }

    /**
     * 取得网络请求返回的字符串内容
     *
     * @param response
     * @param defaultCharset 默认字符集
     * @return 返回的字符串内容
     */
    public static String getHttpResponseString(HttpResponse response,
                                               String defaultCharset) {
        String result = null;
        HttpEntity httpEntity = getHttpResponseEntity(response);
        if (Helper.isNotNull(httpEntity)) {
            try {
                result = EntityUtils.toString(httpEntity, defaultCharset);
            } catch (ParseException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    /**
     * 取得网络请求返回的InputStream
     *
     * @param response
     * @return 返回的InputStream
     */
    public static InputStream getHttpResponseInputStream(HttpResponse response) {
        InputStream result = null;
        HttpEntity httpEntity = getHttpResponseEntity(response);
        if (Helper.isNotNull(httpEntity)) {
            try {
                result = httpEntity.getContent();
            } catch (ParseException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    /**
     * 取得网络请求返回的InputSource
     *
     * @param response
     * @param defaultCharset 默认字符集
     * @return 返回的InputSource
     */
    public static InputSource getHttpResponseInputSource(HttpResponse response,
                                                         String defaultCharset) {
        InputSource result = null;
        // result.setEncoding("GB2312");
        HttpEntity httpEntity = getHttpResponseEntity(response);
        if (Helper.isNotNull(httpEntity)) {
            try {
                result = new InputSource();
                result.setEncoding(defaultCharset);
                result.setByteStream(httpEntity.getContent());
            } catch (IllegalStateException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }


    /**
     * 取得网络图片
     *
     * @param urlAddr 图片地址
     * @return 图片Bitmap
     */
    public static Bitmap fetchUrlBitmap(String urlAddr) {
        try {
            URL url = new URL(urlAddr);
            URLConnection c = url.openConnection();
            c.connect(); // 用URLConnection的connect()方法建立连接
            InputStream is = c.getInputStream();
            return BitmapFactory.decodeStream(is);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 取得网络图片
     *
     * @param urlAddr 图片地址
     * @return 图片Drawable
     */
    public static Drawable fetchUrlDrawable(String urlAddr) {
        Drawable result = null;
        Bitmap bitmap = fetchUrlBitmap(urlAddr);
        if (Helper.isNotNull(bitmap)) {
            result = new BitmapDrawable(bitmap);
        }
        return result;
    }

    /**
     * 下载文件
     *
     * @param urlAddr          文件的url地址
     * @param fullSaveFilePath 保存文件到本地的完整路径,包括文件名和后缀名
     * @return 文件的完整路径
     */
    public static File downloadFile(String urlAddr, String fullSaveFilePath) {
        File result = null;
        if (Helper.isNotEmpty(urlAddr)) {
            InputStream in = null;
            FileOutputStream fos = null;
            try {
                URL url = new URL(urlAddr);
                URLConnection conn = url.openConnection();
                in = conn.getInputStream();
                if (Helper.isNotNull(in)) {
                    File file = new File(fullSaveFilePath);
                    if (!file.exists()) {
                        file.getParentFile().mkdirs();
                        file.createNewFile();
                    }
                    fos = new FileOutputStream(file);
                    byte buffer[] = new byte[512];
                    int length = in.read(buffer);
                    while (length > 0) {
                        fos.write(buffer, 0, length);
                        length = in.read(buffer);
                    }
                    result = file;
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (Helper.isNotNull(in)) {
                    try {
                        in.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (Helper.isNotNull(fos)) {
                    try {
                        fos.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        return result;
    }

    /**
     * 上传文件,可传参
     *
     * @param actionUrl
     * @param params
     * @param filePath
     * @param userAgent1
     * @return
     * @throws Exception
     */
    public static String upload(String actionUrl, List<NameValuePair> params, String filePath, String userAgent1) throws Exception {
        File file = Helper.isNotEmpty(filePath) ? new File(filePath) : null;
        return upload(actionUrl, params, file, userAgent1);
    }

    /**
     * 上传文件,可传参(可改文件名)
     *
     * @param actionUrl
     * @param params
     * @param filePath
     * @param fileName
     * @param
     * @return
     * @throws Exception
     */
    public static String upload(String actionUrl, List<NameValuePair> params, String filePath, String fileName, String userAgent1) throws Exception {
        File file = Helper.isNotEmpty(filePath) ? new File(filePath) : null;
        return upload(actionUrl, params, file, fileName, userAgent1);
    }

    /**
     * 上传文件,可传参
     *
     * @param actionUrl
     * @param params
     * @param file
     * @param userAgent1
     * @return
     * @throws Exception
     */
    public static String upload(String actionUrl, List<NameValuePair> params, File file, String userAgent1) throws Exception {
        if (Helper.isNotNull(file)) {
            return upload(actionUrl, params, file, file.getName(), userAgent1);
        } else {
            return upload(actionUrl, params, file, "", userAgent1);
        }
    }

    /**
     * 上传文件,可传参(可改文件名)
     *
     * @param actionUrl
     * @param params
     * @param file
     * @param fileName   带后缀名的文件名
     * @param userAgent1
     * @return
     * @throws Exception
     */
    public static String upload(String actionUrl, List<NameValuePair> params, File file, String fileName, String userAgent1) throws Exception {
        FormFile[] formFiles = null;
        if (Helper.isNotNull(file) && file.isFile()) {
            byte[] fileBytes = getBytesFromFile(file);
            if (Helper.isNotNull(fileBytes)) {
                formFiles = new FormFile[1];
                formFiles[0] = new FormFile(
                        Helper.isEmpty(fileName) ? file.getName() : fileName
                        , fileBytes
                        , Helper.getFileExtension(file)
                        , ""
                        , "multipart/form-data");
            }
        }
        if (Helper.isNull(formFiles)) {
            formFiles = new FormFile[0];
        }
        return upload(actionUrl, params, formFiles, userAgent1);
    }

    /**
     * 上传文件,可传参(可改文件名)
     *
     * @param actionUrl
     * @param params
     * @param files
     * @param fileName   带后缀名的文件名
     * @param userAgent1
     * @return
     * @throws Exception
     */
    public static String upload(String actionUrl, List<NameValuePair> params, List<File> files, String fileName, String userAgent1) throws Exception {
        FormFile[] formFiles = null;
        if (Helper.isNotNull(files)) {
            int count = files.size();
            formFiles = new FormFile[count];
            for (int i = 0; i < files.size(); i++) {
                byte[] fileBytes = getBytesFromFile(files.get(i));
                if (Helper.isNotNull(fileBytes)) {
                    formFiles[i] = new FormFile(
                            Helper.isEmpty(fileName) ? files.get(i).getName() + i : fileName + i
                            , fileBytes
                            , Helper.getFileExtension(files.get(i))
                            , files.get(i).getName().substring(files.get(i).getName().lastIndexOf(".") + 1, files.get(i).getName().length()).toLowerCase()
                            , "multipart/form-data");
                }
            }
        }
        if (Helper.isNull(formFiles)) {
            formFiles = new FormFile[0];
        }
        return upload(actionUrl, params, formFiles, userAgent1);
    }

    /**
     * 从file转为byte[]
     *
     * @param file
     * @return
     */
    public static byte[] getBytesFromFile(File file) {
        if (file == null) {
            return null;
        }
        FileInputStream stream = null;
        ByteArrayOutputStream out = null;
        try {
            stream = new FileInputStream(file);
            out = new ByteArrayOutputStream(1000);
            byte[] b = new byte[1000];
            int n;
            while ((n = stream.read(b)) != -1) {
                out.write(b, 0, n);
            }
            return out.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (Helper.isNotNull(stream)) {
                try {
                    stream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (Helper.isNotNull(out)) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    /**
     * 上传文件,可传参
     *
     * @param actionUrl
     * @param params
     * @param files
     * @param userAgent1
     * @return
     * @throws Exception
     */
    static int count = 1;

    public static String upload(String actionUrl, List<NameValuePair> params,
                                FormFile[] files, String userAgent1) throws Exception {
//        Log.e("请求次数", count + "");
        count++;
        String result = "";
        JSONObject resultJSONObject = null;
//		try {
        String BOUNDARY = "---------7d4a6d158c9"; // 数据分隔线
        String MULTIPART_FORM_DATA = "multipart/form-data";

        URL url = new URL(actionUrl);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setDoInput(true);// 允许输入
        conn.setDoOutput(true);// 允许输出
        conn.setUseCaches(false);// 不使用Cache
        conn.setConnectTimeout(45000);
        conn.setReadTimeout(45000);
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Connection", "Keep-Alive");
        conn.setRequestProperty("Charset", "UTF-8");
        conn.setRequestProperty("Content-Type", MULTIPART_FORM_DATA
                + "; boundary=" + BOUNDARY);
        if (Helper.isNotEmpty(userAgent1)) {
            conn.addRequestProperty("User-Agent1", userAgent1);
        }
        StringBuilder sb = new StringBuilder();
        DataOutputStream outStream = new DataOutputStream(
                conn.getOutputStream());

        // 上传的表单参数部分
        if (params != null && params.size() > 0) {
            //for (Map.Entry<String, String> entry : params.entrySet()) {// 构建表单字段内容
            for (NameValuePair entry : params) {
                sb.append("--");
                sb.append(BOUNDARY);
                sb.append("\r\n");
                sb.append("Content-Disposition: form-data; name=\""
                        + entry.getName() + "\"\r\n\r\n");
                sb.append(entry.getValue());
                sb.append("\r\n");
            }
            outStream.write(sb.toString().getBytes());// 发送表单字段数据
        }

        // 上传的文件部分
        for (FormFile file : files) {
//				Log.e("","上传文件部分"+file.getData());
            StringBuilder split = new StringBuilder();
            split.append("--")
                    .append(BOUNDARY)
                    .append("\r\n")
                    .append("Content-Disposition: form-data;name=\"")
                    .append(file.getFileName())//.append(file.getFormName())
                    .append("\";filename=\"")
                    .append(file.getType())
                    .append("\r\n")
                    .append("Content-Type:image/"+file.getType())
                    .append("\r\n\r\n");
            outStream.write(split.toString().getBytes());
            outStream.write(file.getData(), 0, file.getData().length);
//            Log.e("====",file.getData().length+"");
            outStream.write("\r\n".getBytes());
        }
        byte[] end_data = ("--" + BOUNDARY + "--\r\n").getBytes();// 数据结束标志
        outStream.write(end_data);
        outStream.flush();
        int cah = conn.getResponseCode();
        if (cah == HttpStatus.SC_OK) {
            LogUtil.d(TAG, "upload:上传文件成功!");
            result = "{\"result\":1,\"desc\":\"问题提交成功\"}";
        } else {
            LogUtil.d(TAG, "upload:上传文件失败:返回码=" + cah);
            result = "{\"result\":1,\"desc\":\"问题提交失败,返回码="+ cah+"\"}";
        }
        outStream.close();

        // 获服务器取数据
        InputStream inputStream = conn.getInputStream();
        InputStreamReader inputStreamReader = new InputStreamReader(
                inputStream);
        BufferedReader reader = new BufferedReader(inputStreamReader);// 读字符串用的。
        String inputLine = null;
        StringBuilder resultSb = new StringBuilder();
        // 使用循环来读取获得的数据，把数据都存到result中了
        while (((inputLine = reader.readLine()) != null)) {
            // 我们在每一行后面加上一个"\n"来换行
            resultSb.append(inputLine).append("\n");
        }
        reader.close();// 关闭输入流
        conn.disconnect();
        result = resultSb.toString();
//		} catch (Exception e) {
//			LogUtil.d(TAG, "upload:上传文件失败:" + e);
//		}
        try{
            result = (new JSONObject(result))+"";
        }catch (Exception e) {
            e.printStackTrace();
            result = createSendFailJSON(ActivityHelper.getString(ActivityHelper.getStringResId("zs4gamestring_hint_http_request_fail"))).toString();
        }
        LogUtil.d(TAG, "upload:返回值:" + result);
        return result;
    }

    // 创建错误json
    private static JSONObject createSendFailJSON(String msg){
        JSONResultEntity entity = new JSONResultEntity(
                Extra.JSONReturnResult.FAIL
                , msg);
        return entity.toJSON();
    }
}
